package com.ms.p2p.controller;


import com.ms.common.bean.Message;
import com.ms.common.exception.NoticeException;
import com.ms.common.exception.ResourceNotFoundException;
import com.ms.common.utils.*;
import com.ms.p2p.Constants;
import com.ms.p2p.entity.Page;
import com.ms.p2p.entity.member.Member;

import com.ms.p2p.entity.system.AdminUser;
import com.ms.p2p.template.directive.FlashMessageDirective;
import com.ms.p2p.utils.DictionaryUtils;
import com.ms.p2p.utils.SpringUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyEditorSupport;
import java.io.IOException;
import java.text.ParseException;
import java.util.*;

import static com.ms.common.utils.WebErrors.ERROR_ATTR_NAME;

public class BaseController {

    protected static Logger logger = Logger.getLogger(BaseController.class);

    protected static final String FRONT_ERROR_PAGE = "/common/error";

    protected static final Message successMessage = Message.success("操作成功");
    protected static final Message errorMMessage = Message.error("操作失败");


    
    /** new PageData对象
     * @return
     */
    public PageData getPageData(){
        return new PageData(this.getRequest());
    }
    /**得到request对象
     * @return
     */
    public HttpServletRequest getRequest() {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return request;
    }

    //private static CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);


    public Member getCurrentUser() {
        return  (Member) AppContext.getSessionAttr(Constants.PRINCIPAL_SESSION_NAME);
    }

    public AdminUser getCurrentEmp() {
        return (AdminUser) AppContext.getSessionAttr(Constants.PRINCIPAL_ADMIN_NAME);
    }

    @SuppressWarnings("unchecked")
    public static Page createJSONData(Page pager){
        if(pager == null){
            return null;
        }
        List<?> dataList = pager.getList();
        pager.setList(createJSONData(dataList));
        return pager;
    }
    private static String getValueByOgnl(Object target,String field,String defaultValue) {
        String resultValue = "";

        Object value = null;
        try {
            value = BeanUtils.getProperty(target, field);
        } catch (Exception e) {

            logger.error("系统错误",e);


            return defaultValue;
        }
        if(null != value){
            resultValue = String.valueOf(value);

        }
        return resultValue;
    }
    /**
     * 将page类转换成ligerUI Grid框架所需的JSON格式数据。
     * @param data
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static List<Object> createJSONData(List dataList){
        Map<String, String> fieldMap = new HashMap<String, String>();
        List<Object> list = new ArrayList<Object>();
        HttpServletRequest request = AppContext.getRequest();
        String filedStr = request.getParameter("field");
        if(org.apache.commons.lang.StringUtils.isEmpty(filedStr)){
            return null;
        }
        String[] field = filedStr.split(",");
        String[] dict = org.apache.commons.lang.StringUtils.splitPreserveAllTokens(request.getParameter("dict"), ",");
        String[] i18n = org.apache.commons.lang.StringUtils.splitPreserveAllTokens(request.getParameter("i18n"), ",");
        String[] isdate = org.apache.commons.lang.StringUtils.splitPreserveAllTokens(request.getParameter("isdate"), ",");

        for(Object data: dataList){
            Map<String,String> keyValue = new HashMap<String,String>();
            for(int i = 0; i < field.length;i++){
                String value = getValueByOgnl(data, field[i],"");
                if (i18n != null && i18n[i].trim().length()>0 && !org.apache.commons.lang.StringUtils.isBlank(value)){
                    String fieldName = null;
                    if(fieldMap.containsKey(field[i])){
                        fieldName = fieldMap.get(field[i]);
                    }else{
                        fieldName = org.apache.commons.lang.StringUtils.capitalize(i18n[i]);
                    }
                    String propertiesValue = SpringUtils.
                            getMessage(fieldName + "." + value, null);
                    keyValue.put(field[i], propertiesValue);
                }else if (dict != null && dict[i].trim().length()>0 && !org.apache.commons.lang.StringUtils.isBlank(value)){
                    String propertiesValue =  DictionaryUtils.getValue(dict[i].trim(),value);
                    keyValue.put(field[i], propertiesValue);
                }else if(isdate!=null&&isdate[i].trim().length()>0&&!org.apache.commons.lang.StringUtils.isBlank(value)){
                    String propertiesValue = MsDateUtils.TimeStamp2DateTime(value);
                    keyValue.put(field[i], propertiesValue);

                }
                else{
                    keyValue.put(field[i], value);
                }
            }
            list.add(keyValue);
        }
        return list;
    }




    protected void addActionError(HttpServletRequest request, String message) {
        WebErrors errors = (WebErrors) request.getAttribute(ERROR_ATTR_NAME);
        if (errors == null) {
            errors = WebErrors.create();
            request.setAttribute(ERROR_ATTR_NAME, errors);
        }
        errors.addErrorString(message);
    }
    protected void addFlashMessage(RedirectAttributes redirectAttributes, Message message) {
        if (redirectAttributes != null && message != null) {
            redirectAttributes.addFlashAttribute(FlashMessageDirective.FLASH_MESSAGE_ATTRIBUTE_NAME, message);
        }
    }
    //private static CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);
//    protected  void clearCache(){
//        for (String cacheName:cacheManager.getCacheNames()){
//            cacheManager.getCache(cacheName).clear();
//
//        }
//    }


    protected  void clearToken(){
        AppContext.removeAttribute(Constants.VALIDATE_TOKEN_KEY);
    }

    @InitBinder
    protected void initBinder(WebDataBinder binder) {



            // String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击
            binder.registerCustomEditor(String.class,
                    new PropertyEditorSupport() {
                        @Override
                        public void setAsText(String text) {
                            setValue(text == null ? null : StringEscapeUtils
                                    .escapeHtml4(text.trim()));
                        }

                        @Override
                        public String getAsText() {
                            Object value = getValue();
                            return value != null ? value.toString() : "";
                        }
                    });
            // Date 类型转换
            binder.registerCustomEditor(Date.class,
                    new PropertyEditorSupport() {
                        @Override
                        public void setAsText(String text) {
                            try {
                                setValue(MsDateUtils.parseDate(text, "yyyy-MM-dd HH:mm:ss"));
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }

                    });


    }

    @ExceptionHandler
    public void exceptionHandler(Exception ex, HttpServletResponse response,
                                 HttpServletRequest request) throws IOException, ServletException {
        if (AppContext.isAjax(request)) {

            if (ex.getClass() == NoticeException.class) {
                this.addActionError(request, ex.getMessage());
            } else {
                ex.printStackTrace();
                logger.error("系统错误", ex);
                this.addActionError(request, "系统错误!");
            }
            WebErrors errors = (WebErrors) request
                    .getAttribute(ERROR_ATTR_NAME);
            errors.showErrorAjax(response);
        } else {
            if (ex.getClass() == NoticeException.class) {
                this.addActionError(request, ex.getMessage());
                request.getRequestDispatcher(FRONT_ERROR_PAGE).forward(request,
                        response);
            } else if (ex.getClass() == ResourceNotFoundException.class) {
                response.sendRedirect("/common/resource_not_found");
            } else {
                ex.printStackTrace();
                logger.error("系统错误", ex);
                this.addActionError(request, "系统错误");
                request.getRequestDispatcher(FRONT_ERROR_PAGE).forward(request,
                        response);
            }
        }
    }


    protected String isValidSms(String mobile, String captcha, boolean isValidCaptcha){

        //是否验证图形验证码
        if(isValidCaptcha) {
            //验证码校验
            String code = (String) AppContext.getSessionAttr(Constants.CAPTCHA_SESSION_KEY);
            if (StringUtils.isBlank(code) || StringUtils.isBlank(captcha) || !code.toLowerCase().equals(captcha.toLowerCase())) {
                return "图形验证错误或已过期失效";
            }
        }

        //频繁发送限制
        String cacheKey = "mobile_code_" + mobile;
        Object ct = CacheUtils.getCacheValue("mobileCode", cacheKey);
        if (ct != null && Integer.valueOf(String.valueOf(ct)) >= 10) {
            logger.info(mobile+",发送过于频繁，请您稍后再试！ct="+ct);
            return "发送过于频繁，请您稍后再试！";
        }

        //
        if (ct == null) {
            CacheUtils.setCacheValue("mobileCode", cacheKey, 1);
        } else {
            CacheUtils.setCacheValue("mobileCode", cacheKey, Integer.valueOf(String.valueOf(ct)) + 1);
        }

        return "";
    }
}
